home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Hardware / PCI Driver Development Kit / • Tools / Utility / LogLibrary 950622 / LogDCMDSrc / LogDCMD.c < prev   
Encoding:
C/C++ Source or Header  |  1996-08-20  |  13.3 KB  |  583 lines  |  [TEXT/MPS ]

  1. /*                                    DisplayLogDCMD.c                                */
  2. /*
  3.  * DisplayLogDCMD.c
  4.  * Copyright © 1992-95 Apple Computer Inc. All Rights Reserved.
  5.  * Programmed by Martin Minow,
  6.  *    Internet:    minow@apple.com
  7.  *    AppleLink:    MINOW
  8.  * Version of December 17, 1994
  9.  *
  10.  * Edit History
  11.  *    93.01.09 MM        First public release
  12.  *    93.01.14 MM        Think and MPW generate different record sizes;
  13.  *                    a disaster if you create an Audit Record under
  14.  *                    Think and call Audit compiled under MPW. Also
  15.  *                    added a test for record sizes and included
  16.  *                    record size information in the AuditRecord.
  17.  *    94.07.18 MM        Updated for the new semaphore stuff.
  18.  *    94.12.17 MM        Converted to the LogLibrary for Power PC
  19.  *    95.01.21 MM        Finally got around to debug the DCMD.
  20.  *    95.05.05 MM        Removed "enable on/off", use LogLibrary68
  21.  *    95.05.26 MM        Folded LogLibrary68 back into LogLibrary.
  22.  *
  23.  * This is a MacsBug DCMD that can display LogRecord contents.
  24.  *
  25.  * The following commands are supported:
  26.  *
  27.  *    DisplayLog NAME            Display the specified log (including previously
  28.  *                            displayed elements that can be recovered).
  29.  *    DisplayLog                Display all Log Records.
  30.  *
  31.  * DisplayLog is built by the provided Makefile.
  32.  *
  33.  * This file contains routines that were copied from the Display Log library.
  34.  */
  35. #include <Errors.h>
  36. #include <Finder.h>
  37. #include <Folders.h>
  38. #include <Script.h>
  39. #include <Types.h>
  40. #include <Resources.h>
  41. #include <QuickDraw.h>
  42. #include <Fonts.h>
  43. #include <Events.h>
  44. #include <Windows.h>
  45. #include <Menus.h>
  46. #include <TextEdit.h>
  47. #include <Dialogs.h>
  48. #include <ToolUtils.h>
  49. #include <Memory.h>
  50. #include <Files.h>
  51. #include <OSUtils.h>
  52. #include <OSEvents.h>
  53. #include <Printing.h>
  54. #include <Traps.h>
  55. #include <Gestalt.h>
  56. #include <Processes.h>
  57. #include <StandardFile.h>
  58. #include <LowMem.h>
  59. #include "::Src:LogLibrary.h"
  60. /*
  61.  * This file should be copied from the MacsBug distribution. Note
  62.  * that we have our own display routines: only dcmdDrawString,
  63.  * dcmdDrawLine, and dcmdDrawText are used.
  64.  */
  65. #include "dcmd.h"
  66. #define DEBUG_DCMD    1
  67.  
  68. #ifndef DEBUG_DCMD
  69. #define DEBUG_DCMD    0
  70. #endif
  71.  
  72. #ifndef TRUE
  73. #define TRUE    1
  74. #define FALSE    0
  75. #endif
  76. enum {
  77.     NUL            = 0,
  78.     kOpenQuote    = 0xD2,
  79.     kCloseQuote    = 0xD3
  80. };
  81. #define kLogLinkFailed            ((UniversalProcPtr) (-1L))
  82.  
  83. void                        DCMDDoAllLogRecords(void);
  84. void                        DCMDDoThisLogRecord(
  85.         LogRecordPtr            logRecordPtr
  86.     );
  87. void                        DCMDDoLogEntryRange(
  88.         LogRecordPtr            logRecordPtr,
  89.         UInt32                    startIndex,
  90.         UInt32                    endIndex
  91.     );
  92. #define AppendChar(result, theChar)    do {                \
  93.         StringPtr        _dst = (result);                \
  94.         _dst[++_dst[0] & 0xFF] = theChar;                \
  95.     } while (0)
  96. void                        PutUnsignedLeadingZeros(
  97.         UInt32                    value,
  98.         short                    digits,
  99.         unsigned char            terminator
  100.     );
  101. void                        PutHexLeadingZeros(
  102.         UInt32                    value,
  103.         short                    digits
  104.     );
  105. void                        PutUnsigned(
  106.         UInt32                    value
  107.     );
  108. void                        PutSigned(
  109.         SInt32                    value
  110.     );
  111. void                        PutUnsignedInField(
  112.         UInt32                    value,
  113.         short                    fieldWidth
  114.     );
  115. void                        PutChar(
  116.         unsigned char            datum
  117.     );
  118. void                        PutPascalString(
  119.         ConstStr255Param        datum
  120.     );
  121. void                        PutCString(
  122.         const char                *datum
  123.     );
  124. pascal void                    CommandEntry(
  125.         dcmdBlock                *paramPtr
  126.     );
  127. pascal void                    dcmdSwapWorlds(void);
  128. void                        PutLine(void);
  129.  
  130. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  131.  * CommandEntry
  132.  *
  133.  * Here's where the DCMD "manager" calls us.
  134.  */
  135. pascal void
  136. CommandEntry(
  137.         dcmdBlock                *paramPtr
  138.     )
  139. {
  140.         Str255                    logRecordName;
  141.         LogRecordPtr            logRecordPtr;
  142.         
  143.         switch (paramPtr->request) {
  144.         case dcmdInit:
  145.             (void) GetLogRecordPtr("");        /* Force CodeFragment load    */
  146.             if (1) {                        /* Testing only                */
  147.                 OSErr                    status;
  148.                 THz                        currentHeap;
  149.                 CFragConnectionID        connectionID;
  150.                 Ptr                        mainEntryAddr;
  151.                 Str255                    errorName;
  152.  
  153.                 currentHeap = GetZone();
  154.                 SetZone(SystemZone());
  155.                 status = GetSharedLibrary(
  156.                             "\pLogLibrary",
  157.                             kPowerPCCFragArch,
  158.                             kLoadCFrag,
  159.                             &connectionID,
  160.                             &mainEntryAddr,
  161.                             errorName
  162.                         );
  163.                 SetZone(currentHeap);
  164.                 if (status != noErr) {
  165.                     PutPascalString("\pNo LogLibrary: ");
  166.                     PutSigned(status);
  167.                     PutPascalString("\p - ");
  168.                     PutPascalString(errorName);
  169.                     PutLine();
  170.                 }
  171.             }
  172.             break;
  173.         case dcmdDoIt:        
  174.             dcmdSwapWorlds();                /* TMON needs this            */
  175.             logRecordName[0] = 0;
  176.             (void) dcmdGetNextParameter(logRecordName);
  177.             if (logRecordName[0] == 0)
  178.                 DCMDDoAllLogRecords();
  179.             else {
  180.                 PutPascalString("\pLogRecord \"");
  181.                 PutPascalString(logRecordName);
  182.                 PutPascalString("\p\"");
  183.                 PutLine();
  184.                 /*
  185.                  * Convert the Pascal string to a CString.
  186.                  */
  187.                 logRecordName[logRecordName[0] + 1] = NUL;
  188.                 logRecordPtr = GetLogRecordPtr((char *) &logRecordName[1]);
  189.                 if (logRecordPtr == NULL) {
  190.                     PutPascalString("\p\"");
  191.                     PutPascalString(logRecordName);
  192.                     PutPascalString("\p\" was not found");
  193.                     PutLine();
  194.                     dcmdSwapWorlds();
  195.                     goto drawHelp;
  196.                 }
  197.                 else {
  198.                     PutLine();
  199.                     DCMDDoThisLogRecord(logRecordPtr);
  200.                 }
  201.             }
  202.             dcmdSwapWorlds();                /* TMON needs this        */
  203.             break;
  204.         case dcmdHelp:
  205.             dcmdDrawLine("\pDisplayLog formats LogRecord areas.");
  206. drawHelp:    dcmdDrawLine("\pFormat:");
  207.             dcmdDrawLine("\pDisplayLog         Write all Log Records.");
  208.             dcmdDrawLine("\pDisplayLog NAME       Write this Log Record only.");
  209.             dcmdDrawLine("\p");
  210.             break;
  211.         }
  212. }
  213.  
  214. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  215.  * DCMDDoAllLogRecords
  216.  *
  217.  * Enumerate through the Log Record entries in the Name Registry.
  218.  */
  219. void
  220. DCMDDoAllLogRecords(void)
  221. {
  222.         OSErr                    status;
  223.          LogRecordIter            cookie;
  224.         LogRecordPtr            logRecordPtr;
  225.         UInt32                    count;
  226.  
  227.         /*
  228.          * First pass just lists the records.
  229.          */
  230.         status = LogRecordIterateCreate(&cookie);
  231.         if (status != noErr) {
  232.             PutPascalString("\pCan't create log record iterator: ");
  233.             PutSigned(status);
  234.             PutLine();
  235.         }
  236.         else {
  237.             count = 0;
  238.             while ((logRecordPtr = LogRecordIterate(&cookie)) != NULL) {
  239.                 ++count;
  240.                 PutPascalString("\p ");
  241.                 PutCString((const char *) logRecordPtr->logName);
  242.                 PutPascalString("\p at ");
  243.                 PutHexLeadingZeros((UInt32) logRecordPtr, 8);
  244.                 PutLine();
  245.             }
  246.             LogRecordIterateDispose(&cookie);
  247.             PutUnsigned(count);
  248.             PutPascalString(
  249.                 (count == 1) ? "\p LogRecord found" : "\p LogRecords found"
  250.             );
  251.             PutLine();
  252.             /*
  253.              * Second pass does the work.
  254.              */        
  255.             status = LogRecordIterateCreate(&cookie);
  256.             if (status == noErr) {
  257.                 while ((logRecordPtr = LogRecordIterate(&cookie)) != NULL)
  258.                     DCMDDoThisLogRecord(logRecordPtr);
  259.                 LogRecordIterateDispose(&cookie);
  260.             }
  261.         }
  262. }
  263.  
  264. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  265.  * DCMDDoThisLogRecord
  266.  *
  267.  * We have a LogRecord. Fetch a copy of the static part of the record, display the
  268.  * fixed information, then display all LogEntries.
  269.  */
  270. void
  271. DCMDDoThisLogRecord(
  272.         LogRecordPtr            logRecordPtr
  273.     )
  274. {
  275.         LogRecord                logRecordCopy;
  276.         OSErr                    status;
  277. #define LOG (logRecordCopy)
  278.  
  279.         if (logRecordPtr != NULL) {
  280.             PutPascalString("\p• LogRecord \"");
  281.             PutCString((const char *) logRecordPtr->logName);
  282.             PutPascalString("\p\", at ");
  283.             PutHexLeadingZeros((UInt32) logRecordPtr, 8);
  284.             PutLine();
  285.             status = CopyLogRecordInfo(logRecordPtr, &logRecordCopy);
  286.             if (status != noErr) {
  287.                 PutPascalString("\pCould not copy log record: ");
  288.                 PutSigned(status);
  289.                 PutLine();
  290.             }
  291.             else {
  292.                 if (LOG.semaphore != 0) {
  293.                     PutPascalString("\p  ••• Semaphore locked •••\n");
  294.                     PutLine();
  295.                 }
  296.                 if (LOG.lostLockCounter != 0) {
  297.                     PutPascalString("\p  Lost Semaphore Counter ");
  298.                     PutUnsigned(LOG.lostLockCounter);
  299.                     PutLine();
  300.                 }
  301.                 PutPascalString("\p  Sequence Counter ");
  302.                 PutUnsigned(LOG.sequenceCounter);
  303.                 PutPascalString("\p, Flags = "); 
  304.                 PutHexLeadingZeros(LOG.flags, 8);
  305.                 PutPascalString("\p, ");
  306.                 PutPascalString(
  307.                     ((LOG.flags & kLogDataEnabledMask) != 0)
  308.                         ? "\pEnabled"
  309.                         : "\pDisabled"
  310.                 );
  311.                 PutPascalString("\p, Preserve ");
  312.                 PutPascalString(
  313.                     ((LOG.flags & kLogDataPreserveFirstMask) != 0)
  314.                         ? "\pearliest."
  315.                         : "\pmost recent."
  316.                 );
  317.                 PutLine();
  318.                 if ((LOG.flags & kLogDataWrapAroundMask) != 0) {
  319.                     if (LOG.entryGetIndex < LOG.entryPutIndex) {
  320.                         /*
  321.                          * +------------+
  322.                          * |            |
  323.                          * | Get Index    |    Do Put+1 to End (already displayed)
  324.                          * |            |    Do Start to Get (already displayed)
  325.                          * | Put Index    |    Do Get+1 to Put (yet to be displayed)
  326.                          * |            |
  327.                          * +------------+
  328.                          */
  329.                         DCMDDoLogEntryRange(        /* Already displayed            */
  330.                             logRecordPtr,
  331.                             LOG.entryPutIndex + 1,
  332.                             LOG.entryMaxIndex - 1
  333.                         );
  334.                         DCMDDoLogEntryRange(        /* Already displayed            */
  335.                             logRecordPtr,
  336.                             0,
  337.                             LOG.entryGetIndex
  338.                         );
  339.                         DCMDDoLogEntryRange(        /* Not yet displayed            */
  340.                             logRecordPtr,
  341.                             LOG.entryGetIndex + 1,
  342.                             LOG.entryPutIndex
  343.                         );
  344.                     }
  345.                     else {
  346.                         /*
  347.                          * +------------+
  348.                          * |            |
  349.                          * | Put Index    |    Do Put+1 to Get (already displayed)
  350.                          * |            |    Do Get+1 to End (yet to be displayed)
  351.                          * | Get Index    |    Do Start to Put (yet to be displayed)
  352.                          * |            |
  353.                          * +------------+
  354.                          */
  355.                         DCMDDoLogEntryRange(        /* Already displayed            */
  356.                             logRecordPtr,
  357.                             LOG.entryPutIndex + 1,
  358.                             LOG.entryGetIndex
  359.                         );
  360.                         DCMDDoLogEntryRange(        /* Not yet displayed            */
  361.                             logRecordPtr,
  362.                             LOG.entryGetIndex + 1,
  363.                             LOG.entryMaxIndex - 1
  364.                         );
  365.                         DCMDDoLogEntryRange(        /* Not yet displayed            */
  366.                             logRecordPtr,
  367.                             0,
  368.                             LOG.entryPutIndex
  369.                         );
  370.                     }
  371.                 }
  372.                 else {
  373.                     /*
  374.                      * We haven't wrapped around yet.
  375.                      * +------------+
  376.                      * | 0            |    Untouched
  377.                      * | 1            |    First real entry
  378.                      * |            |
  379.                      * | Get Index    |
  380.                      * |            |    Do Start to Get (already displayed)
  381.                      * | Put Index    |    Do Get+1 to Put (yet to be displayed)
  382.                      * |            |
  383.                      * +------------+
  384.                      */
  385.                      DCMDDoLogEntryRange(            /* Already displayed            */
  386.                         logRecordPtr,
  387.                         1,
  388.                         LOG.entryGetIndex
  389.                     );
  390.                     DCMDDoLogEntryRange(            /* Not yet displayed            */
  391.                         logRecordPtr,
  392.                         LOG.entryGetIndex + 1,
  393.                         LOG.entryPutIndex
  394.                     );
  395.                 }
  396.                 PutPascalString("\p• End of \"");
  397.                 PutCString((const char *) &LOG.logName);
  398.                 PutPascalString("\p\"");
  399.                 PutLine();
  400.             }
  401.         }
  402. }
  403.  
  404. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  405.  * DCMDDoLogEntryRange
  406.  *
  407.  * Process a range of log record entries. Note: the range is inclusive
  408.  */
  409. void
  410. DCMDDoLogEntryRange(
  411.         LogRecordPtr            logRecordPtr,
  412.         UInt32                    startIndex,
  413.         UInt32                    endIndex
  414.     )
  415. {
  416.         LogEntryRecord            thisLogEntry;
  417.         DateTimeRec                eventDateTime;
  418.         UInt32                    residualNanoseconds;
  419.         Str255                    work;
  420.         OSErr                    status;
  421. #define ENTRY (thisLogEntry)
  422.  
  423.         status = noErr;
  424.         while (status == noErr && startIndex <= endIndex) {
  425.             status = CopyLogEntry(logRecordPtr, startIndex, &thisLogEntry);
  426.             if (status == noErr) {
  427.                 /*
  428.                  * This is what we've been waiting for.
  429.                  */
  430.                 LogConvertTimestamp(
  431.                     &thisLogEntry,
  432.                     &eventDateTime,
  433.                     &residualNanoseconds
  434.                 );
  435.                 PutUnsignedInField(ENTRY.sequence, 5);
  436.                 PutPascalString("\p ");
  437. #if 0 /* Testing */
  438.                 PutUnsignedLeadingZeros(eventDateTime.year % 100,        2, '.');
  439.                 PutUnsignedLeadingZeros(eventDateTime.month,            2, '.');
  440.                 PutUnsignedLeadingZeros(eventDateTime.day,                2, ' ');
  441. #endif
  442.                 PutUnsignedLeadingZeros(eventDateTime.hour,                2, ':');
  443.                 PutUnsignedLeadingZeros(eventDateTime.minute,            2, ':');
  444.                 PutUnsignedLeadingZeros(eventDateTime.second,            2, '.');
  445. /* uSec */        PutUnsignedLeadingZeros(residualNanoseconds / 1000L,    6, NUL);
  446.                 FormatLogEntryData(&ENTRY, work);
  447.                 PutPascalString("\p ");
  448.                 PutPascalString(work);
  449.             }
  450.             else if (status == fBsyErr)
  451.                 PutPascalString("\p Semaphore Locked");
  452.             else {
  453.                 PutSigned(status);
  454.                 PutPascalString("\p: strange status");
  455.             }
  456.             PutLine();
  457.             ++startIndex;
  458.         }
  459. #undef ENTRY
  460. }
  461.  
  462. /*
  463.  * Output an n-digit value with leading zeros.
  464.  */
  465. void
  466. PutUnsignedLeadingZeros(
  467.         UInt32                    value,
  468.         short                    digits,
  469.         unsigned char            terminator
  470.     )
  471. {
  472.         if (--digits > 0)
  473.             PutUnsignedLeadingZeros(value / 10, digits, NUL);
  474.         PutChar((value % 10) + '0');
  475.         if (terminator != NUL)
  476.             PutChar(terminator);
  477. }
  478.  
  479. /*
  480.  * Output a signed decimal longword.
  481.  */
  482. void
  483. PutSigned(
  484.         SInt32                    value
  485.     )
  486. {
  487.         if (value < 0) {
  488.             PutChar('-');
  489.             value = (-value);
  490.         }
  491.         PutUnsigned((unsigned long) value);
  492. }
  493.  
  494. /*
  495.  * Output an unsigned decimal longword.
  496.  */
  497. void
  498. PutUnsigned(
  499.         UInt32                    value
  500.     )
  501. {
  502.         if (value >= 10)
  503.             PutUnsigned(value / 10);
  504.         PutChar((value % 10) + '0');
  505. }
  506.  
  507. /*
  508.  * Output a string of hex digits with leading zeros.
  509.  */
  510. void
  511. PutHexLeadingZeros(
  512.         unsigned long            value,
  513.         short                    digits
  514.     )
  515. {
  516.         if (--digits > 0)
  517.             PutHexLeadingZeros(value >> 4, digits);
  518.         value &= 0x0F;
  519.         PutChar((value < 10)
  520.                 ? value + '0'
  521.                 : (value + ('A' - 10))
  522.             );
  523. }
  524.  
  525. /*
  526.  * Output an n-digit decimal value with leading blanks.
  527.  */
  528. void
  529. PutUnsignedInField(
  530.         UInt32                    value,
  531.         short                    fieldWidth
  532.     )
  533. {
  534.         Str15                    work;
  535.         
  536.         NumToString(value, work);
  537.         while (work[0] < fieldWidth) {
  538.             PutChar(' ');
  539.             --fieldWidth;
  540.         }
  541.         PutPascalString(work);
  542. }
  543.  
  544. void
  545. PutPascalString(
  546.         ConstStr255Param        datum
  547.     )
  548. {
  549.         dcmdDrawString(datum);
  550. }
  551.  
  552. void
  553. PutCString(
  554.         const char                *datum
  555.     )
  556. {
  557.         char                    *cp;
  558.         
  559.         for (cp = (char *) datum; *cp != NUL; cp++)
  560.             PutChar(*cp);
  561. }                
  562.  
  563. void
  564. PutChar(
  565.         unsigned char            datum
  566.     )
  567. {
  568.         char            work[1];
  569.         
  570.         if (datum == '\n')
  571.             PutLine();
  572.         else {
  573.             work[0] = datum;
  574.             dcmdDrawText((StringPtr) work, sizeof (char));
  575.         }
  576. }
  577.  
  578. void
  579. PutLine(void)
  580. {
  581.         dcmdDrawLine("\p");
  582. }
  583.